package main

import (
	"fmt"

	PIR "simplepir/pir"
)

const LOGQ = uint64(32)
const SEC_PARAM = uint64(1 << 10)
const CHAR_LEN = uint64(8)

func main() {

	fmt.Println("**********************Step 1. Server init the scheme, parameters and DB***************")
	N := uint64(1 << 22)
	d := uint64(16) * CHAR_LEN
	simplepir := PIR.SimplePIR{}
	params := simplepir.PickParams(N, d, SEC_PARAM, LOGQ)
	fmt.Println("Each single text size:    ", d/(8.0), "B")

	DBstr := PIR.RandomStringSlice(N, d/CHAR_LEN)
	DB := PIR.MakeDBfromStrVec(N, d, &params, DBstr)

	fmt.Println("**********************Step 2. Server setup the A and Hint_client := A * DB*************")

	seed128 := PIR.GenerateSeed128()
	matrix_A, client_state, server_state := PIR.OfflineSetup(&simplepir, DB, params, seed128)
	Info := DB.Info

	fmt.Println("**********************Step 3. Client query index i with width d************************")

	i := uint64(454)
	A_copy := PIR.MakeState(PIR.MatrixRand(params.M, params.N, params.Logq, 0, seed128))
	sk, query := PIR.Query(&simplepir, params, Info, A_copy, i)

	fmt.Println("**********************Step 4. Server answer*******************************************")

	answer := PIR.Answer(&simplepir, DB, params, server_state, matrix_A, query)

	fmt.Println("**********************Step 5. Client recover******************************************")

	vals := PIR.RecoverVec(&simplepir, params, Info, i, client_state, query, answer, A_copy, sk)

	fmt.Println("**********************Step 6. Verify**************************************************")

	PIR.VerifyStr(DBstr, i, params.Logp, vals)
	//PIR.Reconstruct(params.Logp, vals)

}
